
module Distribution.DescaleBars 
        ( descaleToDay
        , descale
        , filterDay
        , filterHour
        , addOneHour
        )
        where

-- imports 
import Types
import Data.Time
-- gets ordered by UTCTime set of Bars for given day
-- and compress them into day bar

descaleToDay d = descale . filterDay d

descale :: [(UTCTime, BarData)] -> BarData
descale x = BarData openPrice maxPrice lowPrice closePrice volume
        where   firstBar   = snd $ head x
                openPrice  = barOpen firstBar
                maxPrice   = foldl (\a (t,b) -> max a (barHigh b)) (barHigh firstBar) x
                lowPrice   = foldl (\a (t,b) -> min a (barLow b)) (barLow firstBar) x
                closePrice = barClose $ snd $ last x
                volume     = foldl (\a (t,b) -> a + (barVolume b)) 0 x
                
filterDay :: Day->[(UTCTime, BarData)]->[(UTCTime, BarData)]
filterDay d = filter (\(t,b) -> d == (utctDay t))

addOneHour :: LocalTime->LocalTime
addOneHour t = utcToLocalTime utc $ addUTCTime (fromInteger 3600) $ localTimeToUTC utc t

filterHour :: LocalTime->[(UTCTime, BarData)]->[(UTCTime, BarData)]
filterHour h = filter filterFunction
        where   filterFunction (t,b)    = ((toLocalTime t) >= lowTime) && ((toLocalTime t) < highTime)
                toLocalTime r           = utcToLocalTime utc r
                hour                    = todHour $ localTimeOfDay h
                highTime                = addOneHour lowTime
                lowTime                 = LocalTime (localDay h) (TimeOfDay hour 0 0)

